package com.significantfiles.snapshot.engine.compiler;

import javassist.CtMethod;
import javassist.NotFoundException;

import org.antlr.stringtemplate.StringTemplate;

import com.significantfiles.snapshot.engine.compiler.model.x.EntityInterfaceIsBrokenException;

public class EntityFieldGenerator {

	private final static StringTemplate GETTER_TMPL;

	private final static StringTemplate SETTER_TMPL;

	private final CtMethod getter;

	static {
		GETTER_TMPL = new StringTemplate(
				"public $type$ $getterName$() { return this.$fieldName$; }");
		SETTER_TMPL = new StringTemplate(
				"public void $setterName$($type$ value) { this.$fieldName$ = value; }");
	}

	public EntityFieldGenerator(final CtMethod getter) {
		if (getter == null)
			throw new NullPointerException();

		this.getter = getter;
	}

	public String createField() throws EntityInterfaceIsBrokenException {
		return "private " + getTypeName() + " " + this.getFieldName() + ";";
	}

	public String createGetter() throws EntityInterfaceIsBrokenException {
		GETTER_TMPL.reset();

		GETTER_TMPL.setAttribute("type", getTypeName());
		GETTER_TMPL.setAttribute("fieldName", getFieldName());
		GETTER_TMPL.setAttribute("getterName", getGetterName());

		return GETTER_TMPL.toString();
	}

	private String getGetterName() {
		return this.getter.getName();
	}

	private String getFieldName() {
		final String name = this.getter.getName();
		return name.substring(3);
	}

	public String getSetterName() {
		final String fieldName = getFieldName();
		return "set" + fieldName;
	}

	public String createSetter() throws EntityInterfaceIsBrokenException {
		SETTER_TMPL.reset();

		SETTER_TMPL.setAttribute("type", getTypeName());
		SETTER_TMPL.setAttribute("fieldName", getFieldName());
		SETTER_TMPL.setAttribute("setterName", getSetterName());

		return SETTER_TMPL.toString();
	}

	public void createOutputPart() {
		;
	}

	public String getTypeName() throws EntityInterfaceIsBrokenException {
		try {
			return this.getter.getReturnType().getName();
		} catch (final NotFoundException e) {
			throw new EntityInterfaceIsBrokenException();
		}
	}
}
